// TestCaseModel
// (c)2007 Mark Bulmahn. mBulmahn@web.de
// License: GPL 2.0
// Project: TestCaseGenerator. http://www.codeplex.com/TestCaseGenerator

using System;
using System.Collections.Generic;
using System.Text;
using TestCaseModel;

namespace TestCaseModel
{
	/// <summary>
	/// This class can generate all possible combinations of a given
	/// number of parameters with a given number of possible classes
	/// per element. Based on 'Combination' which can only handle
    /// numbers. Actually this is only a facade to map human readable
    /// parameter / class combinations to numeric combinations and back again.
	/// </summary>
    public class SimpleGenerator : Combination, ITcGenerator
	{
        int orderOfCombination = 0;

        public int OrderOfCombination
        {
            get { return orderOfCombination; }
            set { orderOfCombination = value; }
        }

		Parameters paramToCombine = null;

		string[,] parameterCombinations = null;
		public string[,] ParameterCombinations
		{
			get { return parameterCombinations; }
		}

		/// <param name="par">Parameter and classes model to build combinations from</param>
		public Parameters ModelParameters
		{
            set
            {
                paramToCombine = value;
                int[] elementStateDef = new int[paramToCombine.Count];
                int i = 0;
                foreach (Parameter p in value.Values)
                {
                    elementStateDef[i] = p.Classes.Count;
                    i++;
                }
                base.Init(elementStateDef);
            }
		}

		/// <summary>
		/// Calculate the numeric combinations
		/// </summary>
		public new void Calculate()
		{
			base.Calculate();
			MapResults();
		}

		/// <summary>
		/// Maps the numeric results into textual parameter/class combinations
		/// </summary>
		private void MapResults()
		{
			int maxClasses = 0;
			foreach (Parameter p in paramToCombine.Values)
			{
				if (p.Classes.Count > maxClasses)
					maxClasses = p.Classes.Count;
			}
			List<List<string>> parameters = new List<List<string>>();
			foreach (Parameter p in paramToCombine.Values)
			{
				List<string> cls = new List<string>();
				foreach (EquivClass cl in p.Classes)
				{
					cls.Add(cl.Id);
				}
				parameters.Add(cls);
			}					

            // fill the parameter names into a simple two dimensional
            // string array
			parameterCombinations =
				new string[base.NumberOfResults + 1, base.NumberOfElements];
			for (int y = 0; y < base.NumberOfResults; y++)
			{
				for (int x = 0; x < base.NumberOfElements; x++)
				{
					parameterCombinations[y + 1, x] = parameters[x][base.Result[y, x]];
				}
			}

            // add the parameter names as a header in row 0
            int i = 0;
            foreach (Parameter p in paramToCombine.Values)
            {
                parameterCombinations[0, i] = p.Name;
                i++;
            }
		}
	}
}
